/**
 * Copyright 2008-2009. Chongqing Communications Industry Services Co.,Ltd Information Technology Branch. All rights
 * reserved. <a>http://www.cqcis.com</a>
 */
package com.cqcis.uip.base.framework.adaptor;

import java.io.IOException;
import java.net.URL;
import java.util.Enumeration;

import org.osgi.framework.Bundle;

import com.cqcis.uip.base.framework.utils.LogServiceThreadFactory.LogThread;

/**
 * 将类加载委托到当前bundle的ClassLoader,
 * 类加载模型非双亲委托模型. 
 * 采用默认的equals和hashCode方法.
 * 
 * @author huangmy
 * @date   2008-3-25
 */
public class CurrentBundleDelegatingClassLoader extends ClassLoader {
	private final ClassLoader bridge; // 代理类加载器
	private final Bundle backingBundle;
	
	/**
	 * bridge为空, 所有的加载操作将被委托到bundle类加载器
	 * 
	 * @param currentBundle
	 */
	public CurrentBundleDelegatingClassLoader(Bundle currentBundle) {
        this(currentBundle, null);
	}

	/**
	 * 委托给当前bundle
	 * 
	 * @param currentBundle 当前BUNDLE
	 * @param bridgeLoader
	 */
	public CurrentBundleDelegatingClassLoader(Bundle currentBundle, ClassLoader bridgeLoader) {
		super(null);
		
		this.backingBundle = currentBundle;
		this.bridge = bridgeLoader;
	}
    
	// 为了避免classloader缓存class, 采用默认的equals和hashCode方法实现.

	@SuppressWarnings("unchecked")
	protected Class findClass(String name) throws ClassNotFoundException {
		try {
			return this.backingBundle.loadClass(name);
		} catch (ClassNotFoundException cnfe) {
			throw cnfe;
		} catch (NoClassDefFoundError ncdfe) {
			throw ncdfe;
		}
	}

	protected URL findResource(String name) {
		URL url = super.findResource(name);		
		if (url == null) {
			url = this.backingBundle.getResource(name);
		}
		
		return url;
	}

	@SuppressWarnings("unchecked")
	protected Enumeration findResources(String name) throws IOException {
		Enumeration er = super.findResources(name);
		if (er == null) {
			er = this.backingBundle.getResources(name);
		}
		
		return er;
	}

	public URL getResource(String name) {
		URL resource = super.getResource(name);
		if (resource == null) {
			resource = this.backingBundle.getResource(name);
		}
		
		return resource;
	}
    
	/**
	 * 注： 不是双亲委托模型, 先用bridge取，然后用bundle查找
	 * 
	 */
	@SuppressWarnings("unchecked")
	protected Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
		Thread t = Thread.currentThread();
		if (t instanceof LogThread) {
			LogThread lt = (LogThread)t;
			lt.setAttribute("loadClass", name);
		}
		
		Class clazz = null;
		try {
			if (bridge != null) {
				clazz = bridge.loadClass(name);
			}
		} catch (ClassNotFoundException cnfe) {
			clazz = findClass(name);
		} 
		
		if (resolve) {
			resolveClass(clazz);
		}
		
		return clazz;
	}
}
